#include<iostream>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/epoll.h>
#include<fcntl.h>
#include<string.h>
#include<map>
#include<set>
#include"muil_thread.h"
#include"redis_connect.h"
#include<utility>
#include <unistd.h>
#include<unordered_map>
using namespace std;


struct message_state
{
    short int state=0;//信息完整度状态
    int account_len;
    int message_len;
    string account;//转发账户
    string message;//转发信息
    string buff;//数据缓冲区，读取全部数据
};

class server
{
    public:
    server(string host ,int port,int nums,int max);//redis服务地址端口，
    ~server();
    void start_epoll(int epoll);
    void organize_fd(int fd);
    void handle_client(int clirnt_socket);//处理客户端的信息
    void newconnect();//新连接
    void set_nonblock(int fd);
    void check_heart();//心跳在机制
    void logerror(string account);//错误日志记录
    void recv_message(int fd); //接收数据
    void handle_message(int fd,vector<string>&account_list);//处理接收的数据
    bool send_message(string recv_account);//发送信息信息
    void deal_heartmessage(string account);//处理心跳包
    void upadte_time(int fd);//更新心跳时间
    bool check_redis_list(string account);//检测account的redis数据库里面是否有数据
    void deal_redis_list(string account);//处理accountredis数据库里面的数据
    void dele_unactive(int fd);//处理失活套接字

    private:
    int HEARTBEAT_INTERVAL=600;
    int HEARTBEAT_TIMEOUT=2000;
    int listen_socket;//监听socket
    int maxlisten;//最大监听数
    struct sockaddr_in address;//绑定地址
    int epoll_fds[4];//epoll实例
    int time=0;//采用轮转法分配fd<4，四个epoll实例（由epoll实例数量来限制范围）
    unordered_map<string ,int>account_sock;//记录账户的心跳和消息socket
    unordered_map<string ,int>accountfd_sock;//记录账户的文件socket
    unordered_map<int,string>sock_account;//心跳和消息socket的账户
    unordered_map<int,string>sock_accountfd;//文件socket对应的账户
    unordered_map<string,message_state>save_message;//存储用户接收到信息
    unordered_map<int,chrono::steady_clock::time_point>socket_time;//记录对应socket的最后活动时间
    set<int>active_sock;//记录和目前处于活跃状态的socket

    threadpool pool;//线程池
    redis_manager redismanager;//redis连接
    int epollfd;//epoll
};